package me.leiusual.sharing.repository

import androidx.lifecycle.LiveData
import androidx.lifecycle.Transformations.switchMap
import androidx.paging.Config
import androidx.paging.PagedList
import androidx.paging.toLiveData
import com.google.gson.JsonObject
import io.reactivex.Single
import me.leiusual.sharing.api.ApiSharing
import me.leiusual.sharing.api.model.OrderCheckout
import me.leiusual.sharing.api.model.OrderLogistics
import me.leiusual.sharing.api.model.orderconfirm.OrderConfirm
import me.leiusual.sharing.api.model.orderdetail.OrderDetail
import me.leiusual.sharing.api.model.orderlist.Content
import me.leiusual.sharing.api.model.orderlist.OrderList
import me.leiusual.sharing.repository.datasource.OrderDataSourceFactory
import me.leiusual.sharing.repository.model.Data
import javax.inject.Inject
import javax.inject.Singleton

/**
 * author: leiusual
 * create on: 2019-07-28
 * description:
 */
@Singleton
class OrderRepository @Inject constructor(
    private val apiSharing: ApiSharing
) {

  fun orderCheck(map: Map<Long, Int>): Single<Unit> {
    return apiSharing.orderCheck(map)
  }

  fun orderConfirm(map: Map<Long, Int>): Single<OrderConfirm> {
    return apiSharing.orderConfirm(map)
  }

  fun orderCheckout(params: OrderCheckout.Request): Single<JsonObject> {
    return apiSharing.orderCheckout(params.addressId, params.openId, params.payType, params.storeCarts, params.other)
  }

  fun orderList(storeId: Long, keyword: String, status: Int): OrderListListing {
    val factory = OrderDataSourceFactory(apiSharing, storeId, keyword, status)
    val loadInitial = switchMap(factory.orderDataSource) { it.loadInitial }
    val pagedList = factory.toLiveData(Config(9, initialLoadSizeHint = 9))
    return OrderListListing(loadInitial, pagedList)
  }

  data class OrderListListing(
      val loadInitial: LiveData<Data<OrderList>>,
      val pagedList: LiveData<PagedList<Content>>
  )

  fun orderDetail(storeId: Long, code: String): Single<OrderDetail> {
    return if (storeId == 0L) {
      apiSharing.orderDetail(code)
    } else {
      apiSharing.orderDetail(storeId, code)
    }
  }

  fun orderRePay(code: String): Single<JsonObject> {
    return apiSharing.orderRePay(code)
  }

  fun orderDelete(code: String): Single<Unit> {
    return apiSharing.orderDelete(code)
  }

  fun orderConfirm(code: String): Single<Unit> {
    return apiSharing.orderConfirm(code)
  }

  fun orderLogistics(number: String, type: String): Single<List<OrderLogistics.Response.RealLogistics.Data>> {
    return apiSharing.orderLogistics(number, type)
        .map {
          OrderLogistics.Response.toRealLogistics(it)?.Traces
        }
  }
}